package com.haiyi.test.dtmoths;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.tomcat.util.codec.binary.Base64;
 
/*非对称加密
 * 1.定义：非对称加密算法需要两个密钥：公开密钥和私有密钥。
 * 对称加密
 * 1.定义：采用单钥密码系统的加密方法，同一个密钥可以同时用作信息的加密和解密，这种加密方法称为对称加密，也称为单密钥加密。
 * JAVA
通过一个key加密解密

加密解密系列

Java 加密解密之对称加密算法DESede
DESede即三重 DES加密算法，也被称为3DES或者Triple  DES。
使用三(或两)个不同的密钥对数据块进行三次(或两次)DES加密(加密一次要比进行普通加密的三次要快)。
三重DES的强度大约和112- bit的密钥强度相当。通过迭代次数的提高了安全性，
但同时也造成了加密效率低的问题。正因DESede算法效率问题，AES算法诞生了。(详见：Java 加密解密之对称加密算法AES)
到目前为止，还没有人给出攻击三重DES的有效方法。对其密钥空间中密钥进行蛮干搜索，
那么由于空间太大，这实际上是不可行的。若用差分攻击的方法，相对于单一DES来说复杂性以指数形式增长。
三重DES有四种模型
(a)DES-EEE3，使用三个不同密钥，顺序进行三次加密变换。
(b)DES-EDE3，使用三个不同密钥，依次进行加密-解密-加密变换。
(c)DES-EEE2，其中密钥K1=K3，顺序进行三次加密变换。
(d)DES-EDE2， 其中密钥K1=K3，依次进行加密-解密-加密变换。
JDK对DESede算法的支持
密钥长度：112位/168位
工作模式：ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128
填充方式：Nopadding/PKCS5Padding/ISO10126Padding/
工作模式和填充方式请参考：     JAVA加密解密基础
十六进制工具类Hex.java，见：DESede加密解密的java实现：DESede.java

 */
public class DESedeUtil {
	
	public static void main(String [] args) throws Exception {
		
		 System.out.println(generateKey());
		 //String  key="DJ0wpVo4nitgqi2QFKzadM25ckf0cfXkw3yCi3lnB2vFITM6pwPWCA4EwSu5Nyhr";
		 String  key="DJ0wpVo4nitgqi2QFKzadM25ckf0cfXk";
		 // String  key=generateKey() ;
		 System.out.println(key);
		 String enDate =encrypt( "123222", key) ;
		 System.out.println("加密后的："+enDate);
		 String deDate=decrypt( enDate, key);
		 System.out.println("解密后的："+deDate);
	}
	
 
	/**
	 * 密钥算法
	 */
	private static final String KEY_ALGORITHM = "DESede";
	
	/**
	 * 加密/解密算法 / 工作模式 / 填充方式
	 * Java 6支持PKCS5Padding填充方式
	 * Bouncy Castle支持PKCS7Padding填充方式
	 */
	private static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";
	
	/**
	 * 生成密钥
	 * @return	密钥
	 * @throws Exception
	 */
	public static String generateKey() throws Exception {
		//实例化密钥生成器
		KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
		//DESede 要求密钥长度为 112位或168位
		kg.init(168);
		//生成密钥
		SecretKey secretKey = kg.generateKey();
		//获得密钥的字符串形式
		return Base64.encodeBase64String(secretKey.getEncoded());
	}
	
	/**
	 * des加密
	 * @param source	源字符串
	 * @param key	密钥
	 * @return	加密后的密文
	 * @throws Exception
	 */
    public static String encrypt(String source, String key) throws Exception {
        byte[] sourceBytes = source.getBytes("UTF-8");
    	byte[] keyBytes = Base64.decodeBase64(key);
    	Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    	cipher.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(keyBytes, KEY_ALGORITHM));
    	byte[] decrypted = cipher.doFinal(sourceBytes);
    	return Base64.encodeBase64String(decrypted);
    }
    
    /**
     * des解密
     * @param encryptStr	密文
     * @param key	密钥
     * @return	源字符串
     * @throws Exception
     */
    public static String decrypt(String encryptStr, String key) throws Exception {
    	byte[] sourceBytes = Base64.decodeBase64(encryptStr);
		byte[] keyBytes = Base64.decodeBase64(key);
    	Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    	cipher.init(Cipher.DECRYPT_MODE,new SecretKeySpec(keyBytes, KEY_ALGORITHM));
    	byte[] decoded = cipher.doFinal(sourceBytes);
    	return new String(decoded, "UTF-8");
    }
    
}